﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TN_CMS.Admin.Helper.Common;
using TN_CMS.Admin.Models;
using TN_CMS.Domain.Abstract;
using TN_CMS.Domain.Entities;
using TN_CMS.Framework.Helper;
using TN_CMS.Framework.Variable;

namespace TN_CMS.Admin.Controllers
{
    public class SystemController : TNController
    {
        private readonly ISysAdminRepository _sysAdminRepository;
        private readonly ISysFeatureRepository _sysFeatureRepository;
        private readonly ISysRoleRepository _sysRoleRepository;
        private readonly ICommonRepository _commonRepository;

        public SystemController(
            ISysAdminRepository sysAdminRepository,
            ISysFeatureRepository sysFeatureRepository,
            ISysRoleRepository sysRoleRepository,
            ICommonRepository commonRepository)
        {
            this._sysAdminRepository = sysAdminRepository;
            this._sysFeatureRepository = sysFeatureRepository;
            this._sysRoleRepository = sysRoleRepository;
            this._commonRepository = commonRepository;
        }

        #region SysAdmin

        public ActionResult Index()
        {
            var model = new SysAdmin();

            ViewBag.LstRole = new SelectList(this._sysRoleRepository.SysRoles.ToList(), "Id", "Name");

            return View(model);
        }

        [HttpPost]
        public ActionResult GetListSysAdmin(int pageIndex, string orderClause)
        {
            var result = new CustomJsonResult();
            int total = 0;
            int pageSize = AdminHelper.GetPageSize();

            try
            {
                string whereClause = string.Empty;

                var lst = this._sysAdminRepository.GetList(pageIndex, pageSize, out total, orderClause, whereClause);
                result.Result = lst;
                result.Optional = total;
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult GetDetailSysAdmin(int id)
        {
            var result = new CustomJsonResult();

            try
            {
                var detail = new SysAdmin();

                if (id != -1)
                {
                    detail = this._sysAdminRepository.GetDetail(id);
                }
                else
                {
                    detail.Id = -1;
                    detail.CreatedOn = DateTime.Now;
                    detail.IsActive = true;
                }

                result.Result = new
                    {
                        Id = detail.Id,
                        Name = detail.Name,
                        Email = detail.Email,
                        Password = detail.Password,
                        CreatedOn = detail.CreatedOn,
                        CreatedBy = detail.CreatedBy,
                        UpdatedOn = detail.UpdatedOn,
                        UpdatedBy = detail.UpdatedBy,
                        IsActive = detail.IsActive,
                        RecoverCode = detail.RecoverCode,
                        RecoverOn = detail.RecoverOn,
                        LstRole = detail.SysRoles.Select(
                            c => c.Id
                        )
                    };
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult ManageSysAdmin(SysAdmin detail)
        {
            var result = new CustomJsonResult();

            try
            {
                if (this._sysAdminRepository.Save(detail, 1) > 0)
                {
                    // delete mapping
                    this._commonRepository.Delete("SysRolesAdminsMapping", "SysAdminId", Convert.ToString(detail.Id));

                    // insert mapping
                    if (detail.LstRole != null && detail.LstRole.Count > 0)
                    {
                        foreach (int sysRoleId in detail.LstRole)
                        {
                            this._commonRepository.InsertMapping("SysRolesAdminsMapping", "SysRoleId", "SysAdminId", sysRoleId, detail.Id);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult UpdateActiveSysAdmin(int[] arrId, bool isActive)
        {
            var result = new CustomJsonResult();

            try
            {
                this._sysAdminRepository.UpdateActive(arrId, isActive);
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult DeleteSysAdmin(int[] arrId)
        {
            var result = new CustomJsonResult();

            try
            {
                this._sysAdminRepository.Delete(arrId);
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        #endregion

        #region SysFeature

        public ActionResult SysFeature()
        {
            var model = new SysFeature();

            var lstParent = this._sysFeatureRepository.GetAllRoots().ToList();
            lstParent.Insert(0, new SysFeature { Id = -1, Name = "-- Root --" });
            ViewBag.LstParent = new SelectList(lstParent, "Id", "Name");

            return View(model);
        }

        [HttpPost]
        public ActionResult GetListSysFeature(int pageIndex, string orderClause, int parentId)
        {
            var result = new CustomJsonResult();
            int total = 0;
            int pageSize = AdminHelper.GetPageSize();

            try
            {
                string whereClause = string.Empty;

                if (parentId == -1)
                {
                    whereClause += "and C.ParentId is null ";
                }
                else
                {
                    whereClause += string.Format("and C.ParentId = {0} ", parentId);
                }

                var lst = this._sysFeatureRepository.GetList(pageIndex, pageSize, out total, orderClause, whereClause);
                result.Result = lst;
                result.Optional = total;
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult GetDetailSysFeature(int id)
        {
            var result = new CustomJsonResult();

            try
            {
                var detail = new SysFeature();

                if (id != -1)
                {
                    detail = this._sysFeatureRepository.GetDetail(id);

                    if (detail.ParentId == null)
                    {
                        detail.ParentId = -1;
                    }
                }
                else
                {
                    detail.Id = -1;
                    detail.ParentId = -1;
                    detail.ProjectType = EnumProjectType.Admin;
                    detail.IsDisplayOnNav = true;
                    detail.IsActive = true;
                }

                result.Result = new
                {
                    Id = detail.Id,
                    Name = detail.Name,
                    Title = detail.Title,
                    Description = detail.Description,
                    Link = detail.Link,
                    Icon = detail.Icon,
                    ParentId = detail.ParentId,
                    ProjectType = (int)detail.ProjectType,
                    IsDisplayOnNav = detail.IsDisplayOnNav,
                    DisplayOrder = detail.DisplayOrder,
                    IsActive = detail.IsActive
                };
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult ManageSysFeature(SysFeature detail)
        {
            var result = new CustomJsonResult();

            try
            {
                if (detail.ParentId == -1)
                {
                    detail.ParentId = null;
                }
                
                this._sysFeatureRepository.Save(detail);
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult UpdateActiveSysFeature(int[] arrId, bool isActive)
        {
            var result = new CustomJsonResult();

            try
            {
                this._sysFeatureRepository.UpdateActive(arrId, isActive);
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult DeleteSysFeature(int[] arrId)
        {
            var result = new CustomJsonResult();

            try
            {
                this._sysFeatureRepository.Delete(arrId);
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        #endregion

        #region Sys Role

        public ActionResult SysRole()
        {
            var model = new SysRole();

            ViewBag.FeatureDynaTree = this.GetFeatureDynaTree();

            return View(model);
        }

        [HttpPost]
        public ActionResult GetListSysRole(int pageIndex, string orderClause)
        {
            var result = new CustomJsonResult();
            int total = 0;
            int pageSize = AdminHelper.GetPageSize();

            try
            {
                string whereClause = string.Empty;

                var lst = this._sysRoleRepository.GetList(pageIndex, pageSize, out total, orderClause, whereClause);
                result.Result = lst;
                result.Optional = total;
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult GetDetailSysRole(int id)
        {
            var result = new CustomJsonResult();

            try
            {
                var detail = new SysRole();

                if (id != -1)
                {
                    detail = this._sysRoleRepository.GetDetail(id);
                }
                else
                {
                    detail.Id = -1;
                    detail.IsActive = true;
                }

                result.Result = new
                {
                    Id = detail.Id,
                    Name = detail.Name,
                    Key = detail.Key,
                    Description = detail.Description,
                    IsSystemRole = detail.IsSystemRole,
                    IsActive = detail.IsActive
                };
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult ManageSysRole(SysRole detail)
        {
            var result = new CustomJsonResult();

            try
            {
                this._sysRoleRepository.Save(detail);
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult UpdateActiveSysRole(int[] arrId, bool isActive)
        {
            var result = new CustomJsonResult();

            try
            {
                this._commonRepository.UpdateActive("SysRoles", "IsActive", "Id", CommonHelper.ConvertArrIdToStr(arrId), isActive);
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult DeleteSysRole(int[] arrId)
        {
            var result = new CustomJsonResult();

            try
            {
                this._sysRoleRepository.Delete(arrId);
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        private List<DynaTreeNode> GetFeatureDynaTree()
        {
            var result = new List<DynaTreeNode>();

            var lstProject = Enum.GetValues(typeof(EnumProjectType)).Cast<EnumProjectType>().ToList();

            if (lstProject != null && lstProject.Count > 0)
            {
                foreach (var project in lstProject)
                {
                    var projectNode = new DynaTreeNode();
                    projectNode.title = project.ToString();
                    projectNode.key = "project_" + (int)project;
                    projectNode.isFolder = true;

                    #region Get Feature

                    var lstFeature = this._sysFeatureRepository.GetAllByParentAndProject(null, project);

                    if (lstFeature != null && lstFeature.Count > 0)
                    {
                        projectNode.children = new List<DynaTreeNode>();

                        foreach (var feature in lstFeature)
                        {
                            var featureNode = new DynaTreeNode();
                            featureNode.title = feature.Name;
                            featureNode.key = "dynaTreeNodeKey_" + feature.Id;

                            #region Get Feature Child

                            var lstChildFeature = this._sysFeatureRepository.GetAllByParentAndProject(feature.Id, (EnumProjectType)feature.ProjectType);

                            if (lstChildFeature != null && lstChildFeature.Count > 0)
                            {
                                featureNode.children = new List<DynaTreeNode>();

                                foreach (var childFeature in lstChildFeature)
                                {
                                    var featureChildNode = new DynaTreeNode();
                                    featureChildNode.title = childFeature.Name;
                                    featureChildNode.key = "dynaTreeNodeKey_" + childFeature.Id;

                                    featureNode.children.Add(featureChildNode);
                                }
                            }

                            #endregion

                            projectNode.children.Add(featureNode);
                        }
                    }

                    #endregion

                    result.Add(projectNode);
                }
            }

            return result;
        }

        [HttpPost]
        public ActionResult GetRole_FeatureList(int itemId)
        {
            CustomJsonResult result = new CustomJsonResult();

            try
            {
                var lst = this._commonRepository.GetMappingList("SysRolesFeaturesMapping", "SysFeatureId", "SysRoleId", itemId);

                result.Result = lst;
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        [HttpPost]
        public ActionResult ManageRole_Feature(int itemId, int[] arrDelId, int[] arrNewId)
        {
            var result = new CustomJsonResult();

            try
            {
                if (arrDelId != null && arrDelId.Length > 0)
                {
                    for (int i = 0; i < arrDelId.Length; i++)
                    {
                        this._commonRepository.DeleteMapping("SysRolesFeaturesMapping", "SysRoleId", "SysFeatureId", itemId, arrDelId[i]);
                    }
                }

                if (arrNewId != null && arrNewId.Length > 0)
                {
                    for (int i = 0; i < arrNewId.Length; i++)
                    {
                        this._commonRepository.InsertMapping("SysRolesFeaturesMapping", "SysRoleId", "SysFeatureId", itemId, arrNewId[i]);
                    }
                }
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return Json(result);
        }

        #endregion
    }
}
